//
//  simplest_eagl_rgb_render_shader.h
//  QH_Simplest_EAGL_Demo
//
//  Created by Anakin chen on 2021/2/17.
//

#ifndef simplest_eagl_rgb_render_shader_h
#define simplest_eagl_rgb_render_shader_h

#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define SHADER_STRING(text) @ STRINGIZE2(text)

NSString *const vvertexShaderString = SHADER_STRING
(
 attribute vec4 position;
 attribute vec2 texcoord;
 varying vec2 v_texcoord;
 
 void main()
 {
     gl_Position = position;
     v_texcoord = texcoord.xy;
 }
);

NSString *const rgbFragmentShaderString = SHADER_STRING
(
 varying highp vec2 v_texcoord;
 uniform sampler2D inputImageTexture;
 
 void main()
 {
     gl_FragColor = vec4(texture2D(inputImageTexture, v_texcoord).rgb, 1);
 }
);

NSString *const rgbFragmentShaderString1 = SHADER_STRING
(
 varying highp vec2 v_texcoord;
 uniform sampler2D inputImageTexture;
 
 void main()
 {
    mediump vec2 temp = v_texcoord;
    mediump vec2 sp = vec2(0.3, 0.3);
    mediump vec2 center = vec2(0.5, 0.5);
    
    mediump vec2 left_top = vec2(center.x - sp.x, center.y - sp.y);
    mediump vec2 right_bottom = vec2(center.x + sp.x, center.y + sp.y);
    
    if ((v_texcoord.x > left_top.x && v_texcoord.x < right_bottom.x) && (v_texcoord.y > left_top.y && v_texcoord.y < right_bottom.y)) {
        
        temp.x = v_texcoord.x + (center.x - v_texcoord.x)/2.0;
        temp.y = v_texcoord.y + (center.y - v_texcoord.y)/2.0;
        
    }
    
     gl_FragColor = vec4(texture2D(inputImageTexture, temp).rgb, 1);
 }
);

NSString *const rgbFragmentShaderString2 = SHADER_STRING
(
 varying highp vec2 v_texcoord;
 uniform sampler2D inputImageTexture;
 
 mediump int w = 4;
 mediump int h = 4;
 uniform mediump vec2 v_mesh[25];
 uniform mediump mat3 h_pt[16];
 uniform mediump vec2 v_mesh_test[2];

 void main() {
    mediump vec2 temp = vec2(-1.0, -1.0);
    for (int i = 0; i <= w; i++) {
        mediump float x = v_mesh[i].x;
        if (x >= v_texcoord.x) {
            for (int j = 0; j <= h; j++) {
                mediump float y = v_mesh[i + j * w].y;
                if (y >= v_texcoord.y) {
                    temp.y = float(j);
                    temp.x = float(i);
                    break;
                }
            }
        }
        if (temp.y > -1.0) {
            break;
        }
    }

    mediump int idx = int(temp.x - 1.0 + (temp.y - 1.0) * 4.0);

//    mediump mat3 pt = h_pt[idx];
//
//    mediump float x = v_texcoord.x;
//    mediump float y = v_texcoord.y;
//    mediump float denominator = pt[0][2] * x + pt[1][2] * y + pt[2][2];
//    mediump float xx = (pt[0][0] * x + pt[1][0] * y + pt[2][0]) / denominator;
//    mediump float yy = (pt[0][1] * x + pt[1][1] * y + pt[2][1]) / denominator;
//
//    gl_FragColor = vec4(texture2D(inputImageTexture, vec2(xx, yy)).rgb, 1);
    
    if (idx == 4) {
        gl_FragColor = vec4(0, 0, 1, 1);
    }
    else {
        gl_FragColor = vec4(texture2D(inputImageTexture, v_texcoord).rgb, 1);
    }
    
//    mediump float r = float(idx) / 16.0;
//    gl_FragColor = vec4(r, 0, 0, 1);
    
//    gl_FragColor = vec4(float(v_mesh_test[1].x), float(v_mesh_test[1].y), 0.0, 1.0);
 }
);

/*
 * [c++ 怎么判断1个点在一个不规则的四边形内](https://zhidao.baidu.com/question/78277938.html?qbl=relate_question_0&word=%D6%AA%B5%C0%D2%BB%B8%F6%CB%C4%B1%DF%D0%CE%BA%CD%D2%BB%B8%F6%B5%E3%2C%C8%E7%BA%CE%C5%D0%B6%CF%B8%C3%B5%E3%CA%C7%B7%F1%D4%DA%CB%C4%B1%DF%D0%CE%C0%EF%C3%E6)
 效果不好，不使用
 */
NSString *const rgbFragmentShaderString3 = SHADER_STRING
(
  varying highp vec2 v_texcoord;
  uniform sampler2D inputImageTexture;
  
  mediump int w = 4;
  mediump int h = 4;
  uniform mediump float v_mesh[50];
  uniform mediump mat3 h_pt[16];
  uniform mediump vec2 v_mesh_test[2];
  
  void main() {
    mediump int ws = (4 + 1) * 2;
    mediump int idx = -1;
    mediump float fx = v_texcoord.x;
    mediump float fy = v_texcoord.y;
    for (int j = 0; j < h; j++) {
        idx = -1;
        for (int i = 0;i < w; i++) {
            mediump int xp = i * 2 + j * ws;
            mediump int xxp = xp + ws;
            
            mediump float x[4];
            mediump float y[4];
            mediump float ty[4];
            
            x[0] = v_mesh[xp];
            x[1] = v_mesh[xp + 2];
            x[3] = v_mesh[xxp];
            x[2] = v_mesh[xxp + 2];
            
            y[0] = v_mesh[xp + 1];
            y[1] = v_mesh[xp + 3];
            y[3] = v_mesh[xxp + 1];
            y[2] = v_mesh[xxp + 3];
            
            mediump float flag[2];
            mediump float k[2];

            for (int i=0;i<=1;i++) {
                if(x[i] != x[i+1]) {
                    k[i]=(y[i]-y[i+1])/(x[i]-x[i+1]);
                }
            }
            for (int i=0;i<=3;i++) {
                if (i == 0 || i == 2) {
                    ty[i]=k[0]*(fx-x[i])+y[i];
                }
                else {
                    ty[i]=k[1]*(fx-x[i])+y[i];
                }
            }
            for (int i=0;i<=1;i++) {
                if (x[i]==x[i+1]) {
                    flag[i]=(x[i]-fx)*(x[i+2]-fx);
                }
                else {
                    flag[i]=(ty[i]-fy)*(ty[i+2]-fy);
                }
            }
            if ((flag[0]*flag[1])>0.0 && (flag[0]+flag[1])<0.0) {
                idx = i + j * 4;
                break;
            }
            else if ((flag[0]*flag[1])==0.0 && (flag[0]+flag[1])<=0.0) {
                idx = i + j * 4;
                break;
            }
        }
        if (idx > -1) {
            break;
        }
    }
    
//    mediump mat3 pt = h_pt[idx];
//
//    mediump float x = v_texcoord.x;
//    mediump float y = v_texcoord.y;
//    mediump float denominator = pt[0][2] * x + pt[1][2] * y + pt[2][2];
//    mediump float xx = (pt[0][0] * x + pt[1][0] * y + pt[2][0]) / denominator;
//    mediump float yy = (pt[0][1] * x + pt[1][1] * y + pt[2][1]) / denominator;
//
//    gl_FragColor = vec4(texture2D(inputImageTexture, vec2(xx, yy)).rgb, 1);
    
    if (idx == 5) {
        gl_FragColor = vec4(0, 0, 1, 1);
    }
    else {
        gl_FragColor = vec4(texture2D(inputImageTexture, v_texcoord).rgb, 1);
    }
  }
);

/*
 * [C语言判断点是否在不规则四边形内部](https://blog.csdn.net/sdsszk/article/details/84978365)
 * 都使用[0, 1]的单位float记录
 */
NSString *const rgbFragmentShaderString4 = SHADER_STRING
(
  varying highp vec2 v_texcoord;
  uniform sampler2D inputImageTexture;
  
  mediump int w = 10;
  mediump int h = 10;
  mediump int c = (w + 1) * (h + 1) * 2;
  mediump int c1 = w * h;
  uniform mediump float v_mesh[242];
  uniform mediump mat3 h_pt[100];
  uniform mediump vec2 v_mesh_test[2];
  
  void main() {

    mediump int ws = (w + 1) * 2;
    mediump int idx = -1;
    mediump float fx = v_texcoord.x;
    mediump float fy = v_texcoord.y;

    for (int j = 0; j < h; j++) {
        for (int i = 0;i < w; i++) {
            mediump int idx_temp = i + j * w;
            mediump int xp = i * 2 + j * ws;
            mediump int xxp = xp + ws;
            
            mediump float x[4];
            mediump float y[4];
            mediump float ty[4];
            
            x[0] = v_mesh[xp];
            x[1] = v_mesh[xp + 2];
            x[3] = v_mesh[xxp];
            x[2] = v_mesh[xxp + 2];
            
            y[0] = v_mesh[xp + 1];
            y[1] = v_mesh[xp + 3];
            y[3] = v_mesh[xxp + 1];
            y[2] = v_mesh[xxp + 3];
            
            mediump float a;
            mediump float b;
            mediump float c;
            mediump float d;//分别存四个向量的计算结果;
            a = (x[1] - x[0])*(fy - y[0]) - (y[1] - y[0])*(fx - x[0]);
            b = (x[2] - x[1])*(fy - y[1]) - (y[2] - y[1])*(fx - x[1]);
            c = (x[3] - x[2])*(fy - y[2]) - (y[3] - y[2])*(fx - x[2]);
            d = (x[0] - x[3])*(fy - y[3]) - (y[0] - y[3])*(fx - x[3]);
            if ((a >= 0.0 && b >= 0.0 && c >= 0.0 && d >= 0.0) || (a <= 0.0 && b <= 0.0 && c <= 0.0 && d <= 0.0)) {
                idx = i + j * w;
                break;
            }
        }
        if (idx > -1) {
            break;
        }
    }
    
//    if (idx == 97) {
//        gl_FragColor = vec4(0, 0, 1, 1);
//    }
//    else  if (idx == 1) {
//        gl_FragColor = vec4(0, 1, 0, 1);
//    }
//    else {
//        gl_FragColor = vec4(texture2D(inputImageTexture, v_texcoord).rgb, 1);
        mediump mat3 pt = h_pt[idx];

        mediump float x = v_texcoord.x;
        mediump float y = v_texcoord.y;
        mediump float denominator = pt[0][2] * x + pt[1][2] * y + pt[2][2];
        mediump float xx = (pt[0][0] * x + pt[1][0] * y + pt[2][0]) / denominator;
        mediump float yy = (pt[0][1] * x + pt[1][1] * y + pt[2][1]) / denominator;

        gl_FragColor = vec4(texture2D(inputImageTexture, vec2(xx, yy)).rgb, 1);
//    }
    
  }
);

#endif /* simplest_eagl_rgb_render_shader_h */
